libobs_source_macro/
fields.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::{punctuated::Punctuated, token::Comma, Field};
4
5pub fn generate_struct_fields(fields: &Punctuated<Field, Comma>) -> (Vec<TokenStream>, Vec<TokenStream>) {
6    let maybe_obs_properties = fields
7        .iter()
8        .map(|f| {
9            let attr = f.attrs.iter().find(|e| e.path().is_ident("obs_property"));
10
11            (f, attr)
12        })
13        .collect::<Vec<_>>();
14
15    let obs_properties = maybe_obs_properties
16        .iter()
17        .filter_map(|(f, attr)| if attr.is_some() { Some(f) } else { None })
18        .collect::<Vec<_>>();
19
20    let non_obs_properties = maybe_obs_properties
21        .iter()
22        .filter_map(|(f, attr)| if let Some(_a) = attr { None } else { Some(f) })
23        .collect::<Vec<_>>();
24
25    let mut struct_fields = Vec::<TokenStream>::new();
26    let mut struct_initializers = Vec::<TokenStream>::new();
27
28    for field in obs_properties {
29        let name = &field.ident;
30        struct_fields.push(quote! {
31            /// IGNORE THIS FIELD. This is just so intellisense doesn't get confused and isn't complaining
32            #name: u8
33        });
34
35        struct_initializers.push(quote! {
36            #name: 0
37        });
38    }
39
40    for ele in non_obs_properties {
41        let name = &ele.ident;
42        #[allow(dead_code)]
43        let field_type = &ele.ty;
44        struct_fields.push(quote! {
45            #name: #field_type
46        });
47
48        struct_initializers.push(quote! {
49            #name: Default::default()
50        });
51    }
52
53    (struct_fields, struct_initializers)
54}